<?php
declare(strict_types=1);

namespace SixShop\MakerBundle\Generator;

use Symfony\Component\Console\Style\SymfonyStyle;

class ComposerGenerator
{
    private string $templatePath;

    public function __construct()
    {
        $this->templatePath = __DIR__ . '/../../templates/composer.json.tpl.php';
    }

    /**
     * 获取用户输入的包信息
     */
    public function gatherPackageInfo(SymfonyStyle $io, ?string $targetPath = null): ?array
    {
        try {
            // 尝试读取现有的composer.json文件以获取默认值
            $existingInfo = $this->readExistingComposerInfo($targetPath, $io);
            
            // 如果找到了完整的现有信息，询问用户是否直接使用
            if ($this->hasCompleteExistingInfo($existingInfo)) {
                $io->section('发现现有扩展配置');
                $io->table(
                    ['字段', '现有值'],
                    [
                        ['包名', $existingInfo['name'] ?? 'N/A'],
                        ['描述', $existingInfo['description'] ?? 'N/A'],
                        ['命名空间', $existingInfo['namespace'] ?? 'N/A'],
                        ['扩展ID', $existingInfo['id'] ?? 'N/A']
                    ]
                );
                
                if ($io->confirm('确定使用当前配置？', true)) {
                    return [
                        'packageName' => $existingInfo['name'],
                        'description' => $existingInfo['description'],
                        'namespace' => $existingInfo['namespace'],
                        'id' => $existingInfo['id']
                    ];
                }
            }
            
            // 获取包名
            $defaultPackageName = $existingInfo['name'] ?? null;
            $packageName = $io->ask(
                '请输入Composer包名 (例如: six-shop/hello 或sixdec/abc)',
                $defaultPackageName
            );
            
            if (empty($packageName)) {
                throw new \InvalidArgumentException('包名不能为空!');
            }
            
            // 验证包名格式
            if (!preg_match('/^[a-z0-9-_]+\/[a-z0-9-_]+$/', $packageName)) {
                throw new \InvalidArgumentException('包名格式不正确! 正确格式: six-shop/hello 或sixdec/abc');
            }
            
            // 获取包描述
            $defaultDescription = $existingInfo['description'] ?? 'A SixShop extension package';
            $description = $io->ask('请输入包描述 (可选)', $defaultDescription);
            
            // 获取命名空间
            $defaultNamespace = $existingInfo['namespace'] ?? $this->generateDefaultNamespace($packageName);
            // 用户界面显示单反斜杠格式，用户输入也是单反斜杠
            $userNamespace = $io->ask('请输入命名空间 (例如: SixShop\\Hello\\)', $defaultNamespace);
            // PHP代码内部使用单反斜杠存储
            $namespace = rtrim($userNamespace, '\\') . '\\';
            
            // 获取扩展ID
            $defaultId = $existingInfo['id'] ?? str_replace('/', '-', $packageName);
            $id = $io->ask('请输入扩展ID (例如: six-shop-hello)', $defaultId);
            
            return [
                'packageName' => $packageName,
                'description' => $description,
                'namespace' => $namespace,
                'id' => $id
            ];
        } catch (\InvalidArgumentException $e) {
            $io->error($e->getMessage());
            return null;
        }
    }
    
    /**
     * 生成默认命名空间
     */
    private function generateDefaultNamespace(string $packageName): string
    {
        $parts = explode('/', $packageName);
        $vendor = $this->convertToNamespace($parts[0]);
        $package = $this->convertToNamespace($parts[1]);
        return $vendor . '\\' . $package . '\\';
    }
    
    /**
     * 将字符串转换为命名空间格式
     */
    private function convertToNamespace(string $string): string
    {
        $parts = explode('-', $string);
        $parts = array_map('ucfirst', $parts);
        return implode('', $parts);
    }
    
    /**
     * 读取现有的composer.json文件以获取默认值
     */
    private function readExistingComposerInfo(?string $targetPath, SymfonyStyle $io): array
    {
        $existingInfo = [];
        
        if ($targetPath === null) {
            return $existingInfo;
        }
        
        if (is_dir($targetPath)) {
            // 首先检查目标目录下是否直接有composer.json文件
            $directComposerPath = $targetPath . '/composer.json';
            if (file_exists($directComposerPath)) {
                $existingInfo = $this->parseComposerFile($directComposerPath, $io);
                if (!empty($existingInfo)) {
                    return $existingInfo;
                }
            }
            
            // 然后扫描目标目录下的所有子目录，查找composer.json文件
            $directories = array_filter(glob($targetPath . '/*'), 'is_dir');
            
            foreach ($directories as $dir) {
                $composerPath = $dir . '/composer.json';
                if (file_exists($composerPath)) {
                    $existingInfo = $this->parseComposerFile($composerPath, $io);
                    if (!empty($existingInfo)) {
                        // 只取第一个找到的文件
                        break;
                    }
                }
            }
        }
        
        return $existingInfo;
    }
    
    /**
     * 解析composer.json文件并提取相关信息
     */
    private function parseComposerFile(string $composerPath, SymfonyStyle $io): array
    {
        $existingInfo = [];
        
        $composerContent = file_get_contents($composerPath);
        if ($composerContent !== false) {
            $composerData = json_decode($composerContent, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($composerData)) {
                $io->note('发现现有的composer.json文件: ' . $composerPath);
                
                // 提取相关信息
                $existingInfo['name'] = $composerData['name'] ?? null;
                $existingInfo['description'] = $composerData['description'] ?? null;
                
                // 从 autoload PSR-4 中提取命名空间
                if (isset($composerData['autoload']['psr-4'])) {
                    $psr4 = $composerData['autoload']['psr-4'];
                    $namespaces = array_keys($psr4);
                    if (!empty($namespaces)) {
                        // 取第一个命名空间，JSON已经解析为单反斜杠，保持PHP内部单反斜杠格式
                        $existingInfo['namespace'] = rtrim($namespaces[0], '\\') . '\\';
                    }
                }
                
                // 从 extra.sixshop 中提取ID
                if (isset($composerData['extra']['sixshop']['id'])) {
                    $existingInfo['id'] = $composerData['extra']['sixshop']['id'];
                }
            }
        }
        
        return $existingInfo;
    }
    
    /**
     * 检查是否有完整的现有信息
     */
    private function hasCompleteExistingInfo(array $existingInfo): bool
    {
        return !empty($existingInfo['name']) && 
               !empty($existingInfo['description']) && 
               !empty($existingInfo['namespace']) && 
               !empty($existingInfo['id']);
    }

    /**
     * 生成composer.json内容
     */
    public function generateContent(string $packageName, string $namespace, string $id, string $description = 'A SixShop extension package'): string
    {
        if (!file_exists($this->templatePath)) {
            throw new \RuntimeException('模板文件不存在: ' . $this->templatePath);
        }

        // 准备模板变量
        $name = $packageName;
        
        // 生成composer.json内容
        ob_start();
        include $this->templatePath;
        return ob_get_clean();
    }

    /**
     * 保存composer.json文件到指定目录
     */
    public function saveComposerFile(string $packageName, string $content, string $targetPath, SymfonyStyle $io): bool
    {
        $extensionDir = $targetPath;

        // 确保目录存在
        if (!is_dir($extensionDir)) {
            if (!mkdir($extensionDir, 0755, true)) {
                $io->error('无法创建目录: ' . $extensionDir);
                return false;
            }
        }

        $outputPath = $extensionDir . '/composer.json';
        if (file_put_contents($outputPath, $content) !== false) {
            $io->success('composer.json 文件已成功生成: ' . $outputPath);
            return true;
        } else {
            $io->error('无法写入文件: ' . $outputPath);
            return false;
        }
    }

    /**
     * 完整的生成和保存流程
     */
    public function createComposerJson(string $packageName, string $namespace, string $id, string $description, string $targetPath, SymfonyStyle $io): bool
    {
        try {
            // 生成内容
            $content = $this->generateContent($packageName, $namespace, $id, $description);

            // 输出生成的内容
            $io->section('生成的 composer.json 内容:');
            $io->text($content);

            // 询问是否保存文件
            if ($io->confirm('是否将内容保存到 composer.json 文件?', true)) {
                return $this->saveComposerFile($packageName, $content, $targetPath, $io);
            }

            return true;
        } catch (\Exception $e) {
            $io->error('生成 composer.json 时发生错误: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * 完整的从用户输入到生成文件的工作流
     */
    public function createComposerFromUserInput(SymfonyStyle $io, ?string $targetPath = null): bool
    {
        try {
            // 获取用户输入
            $packageInfo = $this->gatherPackageInfo($io);
            
            // 如果没有提供目标路径，使用默认路径
            if ($targetPath === null) {
                $vendorDir = dirname(__DIR__, 5);
                $targetPath = $vendorDir . '/runtime/extension';
            }
            
            // 生成composer.json
            return $this->createComposerJson(
                $packageInfo['packageName'],
                $packageInfo['namespace'],
                $packageInfo['id'],
                $packageInfo['description'],
                $targetPath,
                $io
            );
        } catch (\InvalidArgumentException $e) {
            $io->error($e->getMessage());
            return false;
        }
    }
}